"""
SQLAlchemy ORM 数据模型
"""
import uuid
from datetime import datetime
from sqlalchemy import Column, String, DateTime, Boolean, DECIMAL, CheckConstraint, Index, text, ARRAY, Enum
from sqlalchemy.dialects.postgresql import UUID
try:
    from sqlalchemy.dialects.postgresql import JSONB
except ImportError:
    # 如果JSONB不可用，使用通用JSON类型
    from sqlalchemy import JSON as JSONB
from src.situation.database import Base
from enum import Enum as PyEnum


class RelationshipTypeEnum(PyEnum):
    """关系类型枚举（用于数据库约束和前端选择）"""
    # 指挥隶属关系
    SUBORDINATE_TO = "subordinate_to"  # 隶属于
    COMMAND = "command"  # 指挥
    JURISDICTION = "jurisdiction"  # 管辖

    # 部署与位置关系
    DEPLOYED_AT = "deployed_at"  # 部署在
    STATIONED_AT = "stationed_at"  # 驻扎
    PATROLS = "patrols"  # 巡逻
    DOCKED_AT = "docked_at"  # 停靠

    # 支援与协同关系
    SUPPORTS = "supports"  # 支援
    COORDINATES_WITH = "coordinates_with"  # 协同
    ATTACHED_TO = "attached_to"  # 配属
    COOPERATES_WITH = "cooperates_with"  # 配合

    # 保障与补给关系
    SUPPLIES = "supplies"  # 补给
    MAINTAINS = "maintains"  # 维修
    TRANSPORTS = "transports"  # 运输
    PROVIDES_LOGISTICS = "provides_logistics"  # 后勤保障

    # 观测与侦察关系
    MONITORS = "monitors"  # 监视
    RECONNAISSANCE = "reconnaissance"  # 侦察
    TRACKS = "tracks"  # 跟踪
    OBSERVES = "observes"  # 观察

    # 目标与观测能力关系（新增）
    DETECTS = "detects"  # 探测到
    TRACKS_TARGET = "tracks_target"  # 跟踪目标
    IDENTIFIES = "identifies"  # 识别
    COVERS = "covers"  # 覆盖（观测范围覆盖目标）

    # 防御与防护关系
    PROTECTS = "protects"  # 保护
    GUARDS = "guards"  # 警戒
    INTERCEPTS = "intercepts"  # 拦截
    PROVIDES_COVER = "provides_cover"  # 掩护

    # 通信与数据关系
    COMMUNICATES_WITH = "communicates_with"  # 通信
    DATA_LINK = "data_link"  # 数据链
    COMMAND_CHAIN = "command_chain"  # 指挥链
    INTELLIGENCE_SHARE = "intelligence_share"  # 情报共享

    # 威胁与对抗关系
    THREATENS = "threatens"  # 威胁
    OPPOSES = "opposes"  # 对抗
    JAMS = "jams"  # 干扰
    SUPPRESSES = "suppresses"  # 压制

    # 特定装备关系
    CARRIES = "carries"  # 搭载
    FORMATION = "formation"  # 编队
    ESCORTS = "escorts"  # 护航
    GUIDES = "guides"  # 引导

    # 地理与基础设施关系
    CONNECTS = "connects"  # 连接
    DEPENDS_ON = "depends_on"  # 依赖
    CONTROLS = "controls"  # 控制
    INFLUENCES = "influences"  # 影响


class EquipmentCategoryEnum(PyEnum):
    """装备类别枚举（用于数据库约束）"""
    # 观测装备
    RADAR = "radar"
    OPTICAL = "optical"
    SONAR = "sonar"
    ELINT = "elint"
    SATELLITE = "satellite"
    UAV = "uav"

    # 海上目标
    AIRCRAFT_CARRIER = "aircraft_carrier"
    DESTROYER = "destroyer"
    CRUISER = "cruiser"
    FRIGATE = "frigate"
    SUBMARINE = "submarine"
    AMPHIBIOUS_SHIP = "amphibious_ship"
    MERCHANT_SHIP = "merchant_ship"
    FISHING_VESSEL = "fishing_vessel"

    # 基础设施
    AIRPORT = "airport"
    SEAPORT = "seaport"
    POWER_STATION = "power_station"
    OIL_FIELD = "oil_field"
    TRAIN_STATION = "train_station"

    # 陆上目标
    BRIDGE = "bridge"
    ROAD = "road"
    RAILWAY = "railway"
    TUNNEL = "tunnel"
    DAM = "dam"
    INDUSTRIAL_AREA = "industrial_area"
    RESIDENTIAL_AREA = "residential_area"
    MILITARY_FACILITY = "military_facility"


class SituationObject(Base):
    """态势对象表"""

    __tablename__ = "situation_objects"

    # 主键和基础信息
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4, comment="主键ID")
    object_type = Column(String(50), nullable=False, index=True, comment="对象类型: observation_equipment/infrastructure/sea_target/land_target")
    equipment_category = Column(
        String(50),
        nullable=True,
        index=True,
        comment="装备类别: 与对象类型联动（字符串类型，对应英文枚举值）"
    )
    name = Column(String(200), nullable=False, comment="态势对象名称")
    code = Column(String(100), unique=True, index=True, comment="唯一编码")
    description = Column(String(500), comment="对象描述")

    # 通用基础信息
    model = Column(String(200), comment="型号")
    organization = Column(String(300), comment="所属单位")
    deployment_status = Column(String(50), comment="部署状态: 已部署/待部署/维护中/退役")

    # 通用性能指标
    detection_range = Column(DECIMAL(10, 2), comment="探测距离(km)")
    response_time = Column(DECIMAL(10, 4), comment="响应时间(秒)")
    accuracy = Column(DECIMAL(5, 2), comment="精度(%)")

    # 通用能力维度 (VARCHAR 存储，支持手动填入)
    perception_capability = Column(String(200), comment="感知能力详情")
    communication_capability = Column(String(200), comment="通信能力详情")

    # 适用场景 (VARCHAR 存储，支持手动填入)
    applicable_scenarios = Column(String(200), comment="适用场景列表")

    # 地理位置信息 (VARCHAR 存储，支持手动填入)
    location = Column(String(200), comment="地理位置信息")

    # 类型特定扩展字段 (JSONB 灵活存储)
    type_specific_data = Column(JSONB, nullable=False, default=dict, server_default=text("'{}'::jsonb"), comment="类型特定扩展字段")

    # 通用扩展字段
    extra_metadata = Column(JSONB, default=dict, comment="其他元数据")
    tags = Column(ARRAY(String(200)), default=list, comment="标签数组")

    # 审计字段
    created_at = Column(DateTime, default=datetime.utcnow, nullable=False, comment="创建时间")
    updated_at = Column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow, nullable=False, comment="更新时间")
    created_by = Column(String(100), comment="创建人")
    updated_by = Column(String(100), comment="更新人")

    # 软删除
    is_deleted = Column(Boolean, default=False, nullable=False, index=True, comment="是否已删除")
    deleted_at = Column(DateTime, comment="删除时间")

    # 表约束
    __table_args__ = (
        # 暂时移除严格的类型约束，以便处理旧数据
        # CheckConstraint("object_type IN ('observation_equipment', 'infrastructure', 'sea_target', 'land_target')", name="chk_object_type"),
        Index("idx_situation_objects_tags", "tags", postgresql_using="gin"),
        Index("idx_situation_objects_type_data", "type_specific_data", postgresql_using="gin"),
        Index("idx_situation_objects_object_type_category", "object_type", "equipment_category"),
        # 为VARCHAR字段添加普通索引以支持搜索
        Index("idx_situation_objects_perception_capability", "perception_capability"),
        Index("idx_situation_objects_communication_capability", "communication_capability"),
        Index("idx_situation_objects_applicable_scenarios", "applicable_scenarios"),
        Index("idx_situation_objects_location", "location"),
    )

    def __repr__(self):
        return f"<SituationObject(id={self.id}, type={self.object_type}, name={self.name})>"
